package com.newpage.module_classin.activity;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.alibaba.android.arouter.facade.annotation.Autowired;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
import com.facebook.stetho.common.LogUtil;
import com.google.gson.reflect.TypeToken;
import com.newpage.module_classin.CommandStateEnum;
import com.newpage.module_classin.ConstantCommand;
import com.newpage.module_classin.R;
import com.newpage.module_classin.R2;
import com.newpage.module_classin.service.RoomService;
import com.newpage.module_classin.view.MultipleStateView;
import com.wetao.lib_common.AppConfig;
import com.wetao.lib_common.ConstantArouter;
import com.wetao.lib_common.Constants;
import com.wetao.lib_common.EventBus.EventBusMessage;
import com.wetao.lib_common.EventBus.bean.Answer_command;
import com.wetao.lib_common.EventBus.bean.SingleSwap_command;
import com.wetao.lib_common.EventBus.bean.SmallTest_command;
import com.wetao.lib_common.EventBus.bean.StudentJoinRoom_command;
import com.wetao.lib_common.base.BaseActivity;
import com.wetao.lib_common.base.BasePresenter;
import com.wetao.lib_common.base.BaseViewImp;
import com.wetao.lib_common.bean.ActionCommand;
import com.wetao.lib_common.bean.response.ClassAnswerInfo;
import com.wetao.lib_common.bean.response.GetSubjectList;
import com.wetao.lib_common.tsdBlePen.TsdService;
import com.wetao.lib_common.utils.ComUtil;
import com.wetao.lib_common.utils.DialogXUtil;
import com.wetao.lib_common.utils.GsonUtil;
import com.wetao.lib_common.utils.JsonUtils;
import com.wetao.lib_common.utils.LogUtils;
import com.wetao.lib_common.utils.MultiClickUtil;
import com.wetao.lib_common.utils.ToastUtil;
import com.zhangke.websocket.WebSocketHandler;
import com.zhangke.websocket.response.ErrorResponse;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;


/**
 * author: zhouyh
 * created on: 4/6/21 2:16 PM
 * description: 上课主界面
 */
@Route(path = ConstantArouter.PATH_CLASSIN_MAINROOMACTIVITY)
public class MainRoomActivity extends BaseActivity implements View.OnClickListener {


    private static final String TAG = "WS";


    @Autowired
    String roomName;  //这个字段是roomId
    @Autowired
    String studentId;
    @Autowired
    String lessonName;

    @BindView(R2.id.tv_class_name)
    TextView tv_class_name;
    @BindView(R2.id.iv_class_exit)
    ImageView iv_class_exit;
    @BindView(R2.id.state_view)
    MultipleStateView stateView;

    //随堂小测指令解析bean
    private SmallTest_command smallTest_command;
    private ClassAnswerInfo classAnswerInfo; //互动单选多选题

    //加入房间标志
    private boolean joinRoom = false;

    //默认时长，如果时间结束未加入进行提示
    private static final int count = 3;

    //是否已经进入作答
    private boolean enterAnswer = false;

    //学生是否主动提交过
    private boolean submited = false;
    //答题指令
    private Answer_command answer_command;
    //标准答案
    private List<String> answerStandard = new ArrayList<>();


    private RoomService.RoomBinder roomBinder;
    private RoomService roomService;

    /**
     * 指令状态
     */
    private CommandStateEnum state = CommandStateEnum.ROOM;


    @Override
    public int getLayoutId() {
        return R.layout.classin_activity_mainroom;
    }

    @Override
    public BasePresenter createPresenter() {
        return null;
    }

    @Override
    public BaseViewImp createView() {
        return null;
    }


    @Override
    public void init() {
        EventBus.getDefault().register(this);
        initEvent();
        initTimer(count);


    }


    private void initEvent() {
        stateView.showLoading();
        tv_class_name.setText(lessonName);
        iv_class_exit.setOnClickListener(this);
    }


    @Override
    public boolean getIsBindTsdService() {
        return false;
    }

    @Override
    public TsdService.OnDataReceiveListener getTsdServiceDataReceiveListener() {
        return null;
    }


    @Override
    protected void onStart() {
        super.onStart();
        onBinderRoomService();
    }


    private void onBinderRoomService() {
        Intent roomIntent = new Intent(this, RoomService.class);
        this.bindService(roomIntent, roomConnection, BIND_AUTO_CREATE);
    }

    private void unBinderRoomService() {
        this.unbindService(roomConnection);
        if (roomService != null) {
            roomService.setRoomConnectListener(null);
        }
        roomService = null;
        roomBinder = null;
    }


    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        System.out.println("down----" + keyCode);
        switch (keyCode) {
            case KeyEvent.KEYCODE_BACK:
                dialogue_back(state);
                return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    /**
     * 处理课堂通知点击事件
     */
    private void onClassClick() {
        if (state == CommandStateEnum.CLASSEXAM) {
            EventBus.getDefault().post(new EventBusMessage(EventBusMessage.EVENT_BUS_ACTION_WEBSOCKE_SMALLTEST, gson.toJson(smallTest_command)));
            if (smallTest_command != null) {
                if (smallTest_command.getIsLine() == 1) {
                    //在线
                    ARouter.getInstance().build(ConstantArouter.PATH_HOMEWORK_LINEACTIVITY)
                            .withString("examName", smallTest_command.getExamName())
                            .withInt("examId", smallTest_command.getExamId())
                            .withInt("publishId", smallTest_command.getPublishId())
                            .withString("roomId", roomName)
                            .withInt("isLine", 1)
                            .withBoolean("joinRoom",joinRoom)
                            .withString("fromPath", ConstantArouter.PATH_CLASSIN_MAINROOMACTIVITY)
                            .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
                            .navigation();
                    //  DialogXUtil.waitDialogDelay("正在打开...", 10 * 1000);
                } else if (smallTest_command.getIsLine() == 2) {
                    //点阵
                    ARouter.getInstance().build(ConstantArouter.PATH_HOMEWORK_CODEACTIVITY)
                            .navigation();
                }
                enterAnswer = true;
            }

        } else if (state == CommandStateEnum.CLASSANSWER) {
            EventBus.getDefault().post(new EventBusMessage(EventBusMessage.EVENT_BUS_ACTION_WEBSOCKE_SINGLESWAP, gson.toJson(classAnswerInfo)));
            ARouter.getInstance().build(ConstantArouter.PATH_CLASSIN_ANSWERACTIVITY)
                    .withString("lessonName", lessonName)
                    .withString("roomName", roomName)
                    .withString("studentId", studentId)
                    .withString("answerInfo", gson.toJson(classAnswerInfo))
                    .withBoolean("mJoinRoom",joinRoom)
                    .navigation();
            enterAnswer = true;
        } else if (state == CommandStateEnum.CLASSPICKANSWER) {
            ToastUtil.reset();
            ToastUtil.initToast("您已经完成抢答，请等待");
            sendCommand(ConstantCommand.COMMAND_STUDENT_RUSH_ANSWER);
            stateView.disposable();

        }
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
        unBinderRoomService();
    }


    @Override
    protected void onResume() {
        super.onResume();
        acquireWakeLock();
    }

    @Override
    protected void onPause() {
        super.onPause();
        submited = false;
        releaseWakeLock();
    }


    /**
     * 处理服务器指令
     *
     * @param message
     */
    private void handleServerMessage(String message) {
        if (message.contains("直播间不存在")) {
            ToastUtil.initToast("直播间不存在");
        } else if (message.contains("|||")) {
            String[] commands = message.split("\\|\\|\\|");
            String command = commands[0]; //指令
            if (command.equals(ConstantCommand.COMMAND_TEACHER_QUIT_ROOM)) {
                //老师端主动退出直播间时
                //学生端强制进行退出
                if (ComUtil.isForeground(MainRoomActivity.this)) {
                    exit();
                    ToastUtil.initToast("授课已结束");
                }
            } else if (commands.length > 1) {
                String content = commands[1]; //内容
                LogUtils.i(TAG + ":content=" +  content);
                if (command.equals(ConstantCommand.COMMAND_EXAM)) {
                    //如果未退出
                    if (enterAnswer) {
                        enterAnswer = false;
                        EventBus.getDefault().post(new EventBusMessage(EventBusMessage.EVENT_BUS_ACTION_NOT_EXIT_ANSWER, null));
                    }
                    state = CommandStateEnum.CLASSEXAM;
                    //随堂小测
                    smallTest_command = SmallTest_command.objectFromData(content);
                    showCommandDialog(Constants.TYPE_CLASSIN_SMALL_TEST, smallTest_command.getExamName());

                } else if (command.equals(ConstantCommand.COMMAND_ANSWER)) {
                    //如果未退出
                    if (enterAnswer) {
                        enterAnswer = false;
                        EventBus.getDefault().post(new EventBusMessage(EventBusMessage.EVENT_BUS_ACTION_NOT_EXIT_ANSWER, null));
                    }
                    //随堂互动
                    state = CommandStateEnum.CLASSANSWER;
                    classAnswerInfo = ClassAnswerInfo.objectFromData(content);
                    showCommandDialog(Constants.TYPE_CLASSIN_ANSWER, null);

                } else if (command.equals(ConstantCommand.COMMAND_RUSH_TO_ANSWER)) {
                    if (enterAnswer) {
                        enterAnswer = false;
                        EventBus.getDefault().post(new EventBusMessage(EventBusMessage.EVENT_BUS_ACTION_NOT_EXIT_ANSWER, null));
                    }
                    //抢答
                    state = CommandStateEnum.CLASSPICKANSWER;
                    showCommandDialog(Constants.TYPE_CLASSIN_PICK_ANSWER, null);

                } else if (command.equals(ConstantCommand.COMMAND_JOIN_ROOM)) {
                    //加入房间
                    joinRoom = true;
                    StudentJoinRoom_command com = new StudentJoinRoom_command();
                    com.setStudentId(studentId);
                    com.setRoomId(roomName);
                    com.setInstructions(ConstantCommand.COMMAND_JOIN_ROOM);
                    EventBus.getDefault().post(new EventBusMessage(EventBusMessage.EVENT_BUS_ACTION_WEBSOCKE_ISROOM, gson.toJson(com)));
                } else if (command.equals(ConstantCommand.COMMAND_STOP_ANSWER)) {
                    //退出测试 包含小测、抢答、互动
                    //如果当前退出命令是抢答，则不进行通知
                    ToastUtil.initToast("作答已结束");
                    if (state == CommandStateEnum.CLASSANSWER) {
                        state = CommandStateEnum.ROOM;
                        if (ComUtil.isForeground(MainRoomActivity.this)) {
                            //已提交
                            if (submited) {
                                LogUtil.i("command:" + "已提交，显示答题结果");
                            } else {
                                //未提交
                                LogUtil.i("command:" + "未提交，被动退出答题");
                                sendAnswerCommand(ConstantCommand.COMMAND_STUDENT_ANSWER_QUESTION, new ArrayList<>());
                                EventBus.getDefault().post(new EventBusMessage(EventBusMessage.EVENT_BUS_ACTION_WEBSOCKE_ANSWER_EXIT, null));
                            }
                        } else {
                            //进入答题界面
                            LogUtil.i("command:" + "被动退出答题");
                            EventBus.getDefault().post(new EventBusMessage(EventBusMessage.EVENT_BUS_ACTION_WEBSOCKE_ANSWER_EXIT, null));
                        }
                    } else if (state == CommandStateEnum.CLASSEXAM) {
                        LogUtil.i("command:" + "随堂小测退出作答");
                        EventBus.getDefault().post(new EventBusMessage(EventBusMessage.EVENT_BUS_ACTION_WEBSOCKE_ANSWER_EXIT, null));
                    }
                    DialogXUtil.dismissAll();
                } else if (command.equals(ConstantCommand.COMMAND_SEND_ANSWER)) {
                    ClassAnswerInfo.AnswerData answerContent = ClassAnswerInfo.AnswerData.objectFromData(content);
                    LogUtil.i("command: answerContent = " + answerContent.getAnswerContent().toString());
                    if (answerContent != null && answerContent.getAnswerContent() != null) {
                        answerStandard.clear();
                        answerStandard.addAll(answerContent.getAnswerContent());
                    }
                    //学生答题不为null且不为简答题
                    if (answer_command != null && answer_command.getType() != 3) {
                        submited = false;
                        showAnswerResult(answer_command.getType());
                    }
                }
            }
        } else {
            ToastUtil.initToast("无法加入直播间，请退出重试");
        }
    }


    /**
     * 显示答题结果
     */
    private void showAnswerResult(int type) {

        Boolean answerResult = false;
        List<String> studentAnswer = answer_command.getAnswers();
        LogUtils.e("提交答案:" + GsonUtil.GsonString(answer_command));
        switch (type) {
            case 1://单选
            case 2://判断题
                //学生进行作答
                if (studentAnswer != null && studentAnswer.size() > 0 && answerStandard.size() > 0) {
                    if (studentAnswer.contains(answerStandard.get(0))) {
                        answerResult = true;
                    }
                } else {
                    //学生未进行作答
                    answerResult = null;
                }
                break;
            case 4://多选
                if (studentAnswer != null && studentAnswer.size() > 0 && answerStandard.size() > 0) {
                    if (answerStandard.containsAll(studentAnswer) && answerStandard.size() == studentAnswer.size()) {
                        //全对
                        answerResult = true;
                    } else if (answerStandard.containsAll(studentAnswer)) {
                        //半对 不判断
                        answerResult = null;
                    }
                } else {
                    //学生未进行作答
                    answerResult = null;
                }
                break;
        }
        if (answerResult != null) {
            stateView.showAnswerResult(String.valueOf(answerResult));
        } else {
            stateView.showRoom();
        }
        /**
         * 显示结果后将作答置空
         */
        if (answer_command != null) {
            answer_command = null;
        }
    }


    /**
     * 发送作答互动指令
     *
     * @param action
     */
    private void sendAnswerCommand(String action, List<String> answer) {
        ActionCommand command = new ActionCommand();
        command.setInstructions(action);
        command.setId(studentId);
        command.setRoomId(roomName);
        command.setAnswerContent(answer);
        WebSocketHandler.getDefault().send(gson.toJson(command));
    }

    /**
     * 发送指令
     *
     * @param action
     */
    private void sendCommand(String action) {
        ActionCommand command = new ActionCommand();
        command.setInstructions(action);
        command.setId(studentId);
        command.setRoomId(roomName);
        WebSocketHandler.getDefault().send(gson.toJson(command));
    }


    public void showCommandDialog(int type, String content) {
        String commandContent = null;
        if (type == Constants.TYPE_CLASSIN_SMALL_TEST) {
            commandContent = "收到随堂小测";
        } else if (type == Constants.TYPE_CLASSIN_ANSWER) {
            commandContent = "收到答题互动";
        } else if (type == Constants.TYPE_CLASSIN_PICK_ANSWER) {
            commandContent = "收到抢答互动";
        }
        DialogXUtil.classCommandDialog(
                commandContent, content, type, new DialogXUtil.OnDialogXListen() {
                    @Override
                    public void onListenDialogOk() {
                        if (MultiClickUtil.isFastClick()){
                            onClassClick();
                        }
                    }

                    @Override
                    public void onListenDialogCancel() {

                    }

                    @Override
                    public void onListenDialogClose() {

                    }
                });
    }

    /**
     * 退出弹框
     *
     * @param state
     */
    public void dialogue_back(CommandStateEnum state) {
        String msg = getString(R.string.class_classin_exit);
        String leftButton = "退出";
//        switch (state) {
//            case ROOM:
//                showToast = false;
//                break;
//            case CLASSANSWER:
//            case CLASSPICKANSWER:
//            case CLASSEXAM:
//                msg = getString(R.string.class_command_exit);
//                leftButton = "放弃";
//                showToast = true;
//                break;
//        }

        DialogXUtil.customDialogShow(msg, leftButton, "取消", new DialogXUtil.OnDialogXListen() {
            @Override
            public void onListenDialogOk() {
                exit();
            }

            @Override
            public void onListenDialogCancel() {
            }

            @Override
            public void onListenDialogClose() {

            }
        });
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void busGetMessage(EventBusMessage messageEvent) {
        int action = messageEvent.getAction();
        //学生主动提交过
        if (action == EventBusMessage.EVENT_BUS_ACTION_WEBSOCKE_SUBMITED) {
            submited = true;
            String str = messageEvent.getMsg();
            answer_command = gson.fromJson(str, Answer_command.class);
            LogUtils.i("command: answer_comand" + answer_command.toString());
            enterAnswer = false;
        } else if (action == EventBusMessage.EVENT_BUS_ACTION_WEBSOCKE_SMALLTEST_COMMIT) {
            LogUtils.i("command: small_test_comand" + JsonUtils.toJson(messageEvent.getMsg()));
            String req = messageEvent.getMsg();
            if (req != null) {
                WebSocketHandler.getDefault().send(req);
            }
            enterAnswer = false;
        } else if (action == EventBusMessage.EVENT_BUS_ACTION_ERROR) {
            //exit(); //不用这个，有可能直接杀死进程，bugly捉不到bug
            finish();
        } else if (action == EventBusMessage.EVENT_BUS_ACTION_BACK_FINISH){
            enterAnswer = false;
        }
    }

    /**
     * 退出
     */
    private void exit() {
        if (joinRoom) {
            sendCommand(ConstantCommand.COMMAND_QUIT_ROOM);
            EventBus.getDefault().post(new EventBusMessage(EventBusMessage.EVENT_BUS_ACTION_WEBSOCKE_ISROOM_EXIT, null));
        }
        finish();
    }

    private final ServiceConnection roomConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
            roomBinder = (RoomService.RoomBinder) binder;
            roomService = roomBinder.getService();
            roomService.setRoomConnectListener(new RoomService.RoomConnectListener() {
                @Override
                public void onConnected() {
                    Log.d(TAG, "连接成功");
                    if (WebSocketHandler.getDefault().isConnect() && !joinRoom) {
                        stateView.showRoom();
                        sendCommand(ConstantCommand.COMMAND_JOIN_ROOM);
                        EventBus.getDefault().post(new EventBusMessage(EventBusMessage.EVENT_BUS_ACTION_ROOM_CONNECT_STATE,"true"));
                    }
                }

                @Override
                public void onConnectFailed(Throwable e) {
                    ToastUtil.initToast("加入课堂失败");
                    Log.d(TAG, "连接失败: " + e.toString());
                }

                @Override
                public void onDisconnect() {
                    if (joinRoom){
                        EventBus.getDefault().post(new EventBusMessage(EventBusMessage.EVENT_BUS_ACTION_ROOM_CONNECT_STATE,"false"));
                    }
                    Log.d(TAG, "连接断开,重新加入房间");
                    WebSocketHandler.getDefault().reconnect();
                    joinRoom = false;
                    sendCommand(ConstantCommand.COMMAND_JOIN_ROOM);
                }

                @Override
                public void onSendDataSuccess() {
                    Log.d(TAG, "发送数据成功");
                    /**
                     * 重连的时候会调用导致在线作业会关闭
                     * 判断是否已经加入房间
                     */
                    if (joinRoom){
                        EventBus.getDefault().post(new EventBusMessage(EventBusMessage.EVENT_BUS_ACTION_SEND_DATA_SUCCESS, ConstantCommand.COMMAND_SEND_SUCCESS));
                    }
                }

                @Override
                public void onSendDataError(ErrorResponse errorResponse) {
                    EventBus.getDefault().post(new EventBusMessage(EventBusMessage.EVENT_BUS_ACTION_SEND_DATA_SUCCESS, ConstantCommand.COMMAND_SEND_FAIL));
                    Log.d(TAG, "发送消息失败" + "请求数据=" + gson.toJson(errorResponse.getRequestData().getRequestData()));
                }

                @Override
                public void onMessage(String message) {
                    Log.d(TAG, "接收消息:" + message);
                    handleServerMessage(message);
                }

                @Override
                public void onMessage(ByteBuffer bytes) {

                }
            });
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            roomService = null;
        }
    };

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.iv_class_exit) {
            dialogue_back(state);
        }
    }


    /**
     * 倒计时
     * 3s无法连接直播间进行提示
     */
    private Disposable disposable;
    private void initTimer(int time) {

        Observable.interval(0, 1, TimeUnit.SECONDS)//设置0延迟，每隔一秒发送一条数据
                .take(time + 1) //设置发送count+1次 因为是count~0秒
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())//操作UI要在UI线程
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                    }

                    @Override
                    public void onComplete() {
                        LogUtils.d("onCompleted: " + System.currentTimeMillis());
                        disposable();
                        if (!joinRoom){
                            ToastUtil.initToast("无法加入直播间，请退出重试");
                        }
                    }
                    @Override
                    public void onSubscribe(Disposable d) {
                        disposable = d;
                    }

                    @Override
                    public void onNext(Long aLong) { //接受到一条就是会操作一次UI

                    }
                });
    }

    public void disposable() {
        if (disposable != null && !disposable.isDisposed()) {
            disposable.dispose();
            disposable = null;
        }
    }
}


